查看原文
其他

RecyclerView实现双列表联动

fatchao 鸿洋 2019-04-05

本文作者


本文由fatchao投稿。

fatchao的博客地址:

http://www.jianshu.com/u/94dc45995a85


1
概述


最近项目中需要实现一个分类页面

UI图



实现要求


  1. 左侧联动右侧:
    点击左侧列表的某一项,背景变色,同时右侧列表中对应的分类滚动到顶部

  2. 右侧列表悬停:
    右侧列表滑动的时候相应的标题栏需要在顶部悬停

  3. 标题栏可点击

  4. 右侧联动左侧:
    滚动右侧列表,监听滚动的位置,左侧列表需要同步选中相应的列表


效果图



对照着上面的UI要求,基本上实现了所有的需求,下面分享一下实现的思路


2

左侧联动右侧


两侧都是Recyclerview,一开始以为就是调用一下Recyclerview的scrollToPostion滚动到具体的位置就好,但是实际上并非如此,因为Recyclerview的滚动方法有两种:


scrollToPosition(int)


但是实际上调用的时候就比较坑爹,分为两种情况


1. 从上往下滚动:


如果是从上往下滚动的时候,发现每次达不到预期的效果,只能将需要滚动的item的显示出来而已,并不能滚动到顶部


2. 从下滚动


这种情况是OK的,每次能够达到想要的效果


scrollBy(int x,int y)


这个方法如果是针对LinearLayoutManager的话,可以动态计算滚动的高度,但是针对相对复杂的布局就非常麻烦,最后找到了一种解决方案:


滚动的position小于FirstVisibleItemPosition

直接调用scrollToPosition:


mRv.smoothScrollToPosition(n);


滚动的position介于FirstVisibleItemPosition与LastVisibleItemPosition之间

获取需要滚动的position距离顶部的高度,然后调用scrollBy


int top = mRv.getChildAt(n - firstItem).getTop(); mRv.smoothScrollBy(0, top);


滚动的position>lastVisibleItemPosition


先调用scrollToPosition将需要滚动的position显示出来,在滚动完成时进行监听,当滚动停止的时候,执行跟2中相同的操作,达到目的


整体代码如下



3

右侧列表悬停


之前有看过张旭童的关于利用itemDecoration来实现城市列表索引的博客,写的的确是挺好的,唯一遗憾的是itemDecoration实现的头部不支持点击,所以这里换了另外一种思路。


Sectioned实现方式


伪造一个头部,给一个标志,然后加入到已有的数据集合中,然后再Recyclerview的Adapter中针对此标志返回标题栏的布局,达到分组的目的



悬停的实现


其实这个利用了itemDecoration,调用RecyclerView.ItemDecoration的onDrawOver中进行绘制一个跟Title一模一样的标题栏就好了,这样就把第一个Section覆盖了,看起来好像是悬停的感觉。


当发现下一个title顶上来的时候,将canvas向上平移,产生一种向上挤压的动画效果



绘制悬停的头部


这里没有一个一个控件的进行绘制,因为单个绘制比较麻烦,所以直接绘制了整个布局,同时修改了布局中标题栏中的内容



4
其他


标题栏可点击


由于是采用的布局而不是itemDecoration的实现,所以所有的标题栏都是可以点击跳转的


右侧联动左侧


当右侧悬停的title内容发生变化的时候,通过一个接口进行回调左侧列表即可,比较简单,贴下代码:



Demo下载地址

https://github.com/wuster2015/GangedRecyclerview


如果你有想学习的文章直接留言,我会整理征稿。如果你有好的文章想和大家分享欢迎投稿,直接向我投递文章链接即可。


欢迎长按下图->识别图中二维码或者扫一扫关注我的公众号:

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存